package platform.util;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
/**
 * 解析sql嵌套 分离select from 
 * @author zrz
 *
 */
public class TokenUtil {
	/**
	 * 获取 第一个select 配对的from的下标
	 * @param hqlStr
	 * @return
	 */
	  public static int getIndex(String hqlStr) {
		    List<SQLToken>  SQLTokenList=new ArrayList<SQLToken>();
			int distance=0;
	 		String hql=hqlStr.toLowerCase();
	 		nestParseCause(hql,SQLTokenList,distance);
	 		SQLToken  sqlToken=backSQLToken(SQLTokenList);
			return sqlToken.getIndex();
	  }
	  /**
	   * 获取 最后一个未配对的from元素（包含下标）
	   * @param SQLTokenList
	   * @return
	   */
	  private static SQLToken backSQLToken(List<SQLToken> SQLTokenList){
		  SQLToken  sqlToken=null;
		  Stack<SQLToken> stack=new Stack<SQLToken>(); 
		  for(int i=1;i<SQLTokenList.size();i++){
			  SQLToken  sqlTokenTemp=SQLTokenList.get(i);
			  if(stack.isEmpty()){
				  if(sqlTokenTemp.getMark()=="from"){
					 sqlToken=sqlTokenTemp;
					 break;
				  }else{
					  stack.push(sqlTokenTemp);
				  }
			  }else{
				 SQLToken  sqlTokenTop=stack.peek();
				 if(sqlTokenTemp.getMark()!=sqlTokenTop.getMark()) {
					 stack.pop();
				 }
			  }
		  }
		  return sqlToken;
	  }
	  /**
	   * 抽取字符串分离出select from元素 
	   * @param hql
	   * @param SQLTokenList
	   * @param distance
	   */
	  private static void nestParseCause(String hql,List<SQLToken>  SQLTokenList,int distance){
			if(hql==null || "".equals(hql)) return;
			int selectIndex=hql.indexOf("select");
			int fromIndex=hql.indexOf("from");
			String subStr="";
			if(selectIndex<fromIndex&&selectIndex!=-1){
				SQLToken t=new SQLToken();
				t.setMark("select");
				t.setIndex(selectIndex+distance);
				SQLTokenList.add(t);
				int tempSize=hql.substring(0, selectIndex+6).length();
				distance+=tempSize;
				subStr=hql.substring(selectIndex+6);
				nestParseCause(subStr,SQLTokenList,distance);
			}
			if(selectIndex!=-1&&fromIndex==-1){
				SQLToken t=new SQLToken();
				t.setMark("select");
				t.setIndex(selectIndex+distance);
				SQLTokenList.add(t);
				int tempSize=hql.substring(0, selectIndex+6).length();
				distance+=tempSize;
				subStr=hql.substring(selectIndex+6);
				nestParseCause(subStr,SQLTokenList,distance);
			}
			if(fromIndex<selectIndex&&fromIndex!=-1){
				SQLToken t=new SQLToken();
				t.setMark("from");
				t.setIndex(fromIndex+distance);
				SQLTokenList.add(t);
				int tempSize=hql.substring(0, fromIndex+4).length();
				distance+=tempSize;
				subStr=hql.substring(fromIndex+4);
				nestParseCause(subStr,SQLTokenList,distance);
			}
			if(fromIndex!=-1&&selectIndex==-1){
				SQLToken t=new SQLToken();
				t.setMark("from");
				t.setIndex(fromIndex+distance);
				SQLTokenList.add(t);
				int tempSize=hql.substring(0, fromIndex+4).length();
				distance+=tempSize;
				subStr=hql.substring(fromIndex+4);
				nestParseCause(subStr,SQLTokenList,distance);
			}
			
		}		  
}
